"""
Tree-sitter 项目级语法树分析系统

这个模块提供了使用Tree-sitter生成全项目语法树和索引关系的完整解决方案。

主要功能：
1. 解析项目中的所有Python文件
2. 生成抽象语法树(AST)
3. 构建符号索引和引用关系
4. 提供查询和搜索功能
5. 支持代码分析和重构

依赖安装：
pip install tree-sitter tree-sitter-python

使用方法：
python tree_sitter_analyzer.py --project-path /path/to/project
"""

import os
import sys
from pathlib import Path
from typing import Dict, List, Optional, Set, Tuple, Any
import json
import argparse
from dataclasses import dataclass, field
from collections import defaultdict

try:
    import tree_sitter
    from tree_sitter import Language, Parser, Node
except ImportError:
    print("请安装tree-sitter: pip install tree-sitter tree-sitter-python")
    sys.exit(1)


@dataclass
class Position:
    """代码位置信息"""
    line: int
    column: int
    
    def __str__(self) -> str:
        return f"{self.line}:{self.column}"


@dataclass
class Range:
    """代码范围信息"""
    start: Position
    end: Position
    
    def __str__(self) -> str:
        return f"{self.start}-{self.end}"


@dataclass
class Symbol:
    """符号信息"""
    name: str
    type: str  # function, class, variable, import, etc.
    file_path: str
    range: Range
    scope: str = ""
    definition_range: Optional[Range] = None
    references: List[Range] = field(default_factory=list)
    children: List['Symbol'] = field(default_factory=list)
    parent: Optional['Symbol'] = None
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            "name": self.name,
            "type": self.type,
            "file_path": self.file_path,
            "range": f"{self.range}",
            "scope": self.scope,
            "definition_range": f"{self.definition_range}" if self.definition_range else None,
            "references": [f"{ref}" for ref in self.references],
            "children_count": len(self.children)
        }


@dataclass
class FileAnalysis:
    """文件分析结果"""
    file_path: str
    ast: Optional[Node] = None
    symbols: List[Symbol] = field(default_factory=list)
    imports: List[Symbol] = field(default_factory=list)
    errors: List[str] = field(default_factory=list)
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            "file_path": self.file_path,
            "symbols_count": len(self.symbols),
            "imports_count": len(self.imports),
            "errors": self.errors,
            "symbols": [symbol.to_dict() for symbol in self.symbols],
            "imports": [imp.to_dict() for imp in self.imports]
        }


class TreeSitterConfig:
    """Tree-sitter配置类"""
    
    def __init__(self):
        self.python_language = None
        self.parser = None
        self._setup_language()
    
    def _setup_language(self):
        """设置Python语言解析器"""
        try:
            # 尝试加载预编译的Python语言库
            from tree_sitter_python import language
            self.python_language = language()
            
            # 创建解析器
            self.parser = Parser()
            self.parser.set_language(self.python_language)
            
        except ImportError:
            print("警告: 无法导入tree_sitter_python，请安装: pip install tree-sitter-python")
            print("或者手动编译Python语言库")
            
            # 备选方案：手动编译（需要clone tree-sitter-python仓库）
            self._compile_python_language()
    
    def _compile_python_language(self):
        """手动编译Python语言库（备选方案）"""
        try:
            # 这需要预先clone tree-sitter-python仓库
            # git clone https://github.com/tree-sitter/tree-sitter-python
            python_lib_path = "tree-sitter-python"
            if os.path.exists(python_lib_path):
                Language.build_library(
                    'build/my-languages.so',
                    [python_lib_path]
                )
                self.python_language = Language('build/my-languages.so', 'python')
                self.parser = Parser()
                self.parser.set_language(self.python_language)
            else:
                print("错误: 无法找到Python语言库")
                sys.exit(1)
        except Exception as e:
            print(f"编译Python语言库失败: {e}")
            sys.exit(1)
    
    def is_ready(self) -> bool:
        """检查是否准备就绪"""
        return self.parser is not None and self.python_language is not None


# Tree-sitter查询模式
PYTHON_QUERIES = {
    # 函数定义
    "function_definitions": """
    (function_definition
      name: (identifier) @function.name
      parameters: (parameters) @function.params
      body: (block) @function.body) @function.definition
    """,
    
    # 类定义
    "class_definitions": """
    (class_definition
      name: (identifier) @class.name
      superclasses: (argument_list)? @class.superclasses
      body: (block) @class.body) @class.definition
    """,
    
    # 变量赋值
    "variable_assignments": """
    (assignment
      left: (identifier) @variable.name
      right: (_) @variable.value) @variable.assignment
    """,
    
    # 导入语句
    "import_statements": """
    (import_statement
      name: (dotted_name) @import.module) @import.statement
    
    (import_from_statement
      module_name: (dotted_name) @import.module
      name: (dotted_name) @import.name) @import.from_statement
    """,
    
    # 函数调用
    "function_calls": """
    (call
      function: (identifier) @call.function
      arguments: (argument_list) @call.arguments) @call
    """,
    
    # 方法调用
    "method_calls": """
    (call
      function: (attribute
        object: (identifier) @call.object
        attribute: (identifier) @call.method)
      arguments: (argument_list) @call.arguments) @call
    """,
    
    # 变量引用
    "variable_references": """
    (identifier) @variable.reference
    """,
}


def get_node_text(node: Node, source_code: bytes) -> str:
    """获取节点对应的源代码文本"""
    return source_code[node.start_byte:node.end_byte].decode('utf-8')


def node_to_position(node: Node) -> Position:
    """将Tree-sitter节点转换为位置信息"""
    return Position(line=node.start_point[0] + 1, column=node.start_point[1])


def node_to_range(node: Node) -> Range:
    """将Tree-sitter节点转换为范围信息"""
    start = Position(line=node.start_point[0] + 1, column=node.start_point[1])
    end = Position(line=node.end_point[0] + 1, column=node.end_point[1])
    return Range(start=start, end=end)


if __name__ == "__main__":
    print("Tree-sitter 项目级语法树分析系统")
    print("使用 python tree_sitter_analyzer.py --help 查看使用方法")